package edu.xust.MetadataGenerator.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.google.gson.annotations.Expose;

public class Table implements Serializable{
	private static final long serialVersionUID = 7615919032917543844L;
	private final static Logger logger = LogManager.getLogger(Table.class);
	private static final long id = Table.generateId();
	
	@Expose
	private String name;

	@Expose
	private String moduleid;

	@Expose
	private String theme;

	@Expose
	private String comment;
	
	@Expose
	private String idFieldName;

	@Expose
	private List<Field> fields;

	//private String fields_zh;
	//private String fields_en;
	
	@Expose
	private List<TableConstraint> constraints;

	@Expose
	private List<API> apis;

	public static String uncapFirst(String s){
		if(null != s && s.length() > 0){
			String first = "" + s.charAt(0);
			first = first.toLowerCase();
			logger.debug(first);
			s = s.substring(1);
			return first + s;
		}
		return s;
	}
	
	public static  String capFirst(String s){
		if(null != s && s.length() > 0){
			String first = "" + s.charAt(0);
			first = first.toUpperCase();
			s = s.substring(1);
			return first + s;
		}
		return s;
	}
	
	public Table(String tableName){
		tableName = capFirst(tableName);
		name = tableName;
		moduleid = "test";
		theme = "metro";
		comment = tableName;
		
		fields = new LinkedList<Field>();
		idFieldName = "id";
		
		//id字段
		Field idField = new Field();
		idField.setName(idFieldName);
		idField.setType("varchar(40)");
		idField.setLabel(idFieldName);
		idField.setComment(idFieldName);
		idField.setPlaceholder(idFieldName);
		List<FieldConstraint> fieldConstraints = new LinkedList<FieldConstraint>();
		FieldConstraint fieldConstraint = new FieldConstraint();
		fieldConstraint.setName("primary key");
		fieldConstraints.add(fieldConstraint);
		idField.setConstraints(fieldConstraints);
		fields.add(idField);
		
		//sys_create_time
		Field field_sys_create_time = new Field();
		field_sys_create_time.setName("sys_create_time");
		field_sys_create_time.setType("datetime");
		field_sys_create_time.setLabel("创建时间");
		field_sys_create_time.setPlaceholder("创建时间");
		field_sys_create_time.setComment("创建时间");
		fields.add(field_sys_create_time);

		//sys_creator
		Field field_sys_creator = new Field();
		field_sys_creator.setName("sys_creator");
		field_sys_creator.setType("varchar(40)");
		field_sys_creator.setLabel("创建者");
		field_sys_creator.setPlaceholder("创建者");
		field_sys_creator.setComment("创建者");
		fields.add(field_sys_creator);

		//sys_update_time
		Field field_sys_update_time = new Field();
		field_sys_update_time.setName("sys_update_time");
		field_sys_update_time.setType("datetime");
		field_sys_update_time.setLabel("上次修改时间");
		field_sys_update_time.setComment("上次修改时间");
		field_sys_update_time.setPlaceholder("上次修改时间");
		fields.add(field_sys_update_time);

		//sys_updator
		Field field_sys_updator = new Field();
		field_sys_updator.setName("sys_updator");
		field_sys_updator.setType("varchar(40)");
		field_sys_updator.setLabel("上次修改者");
		field_sys_updator.setComment("上次修改者");
		field_sys_updator.setPlaceholder("上次修改者");
		fields.add(field_sys_updator);

		//sys_expire_time
		Field field_sys_expire_time = new Field();
		field_sys_expire_time.setName("sys_expire_time");
		field_sys_expire_time.setType("datetime");
		field_sys_expire_time.setLabel("锁定时间");
		field_sys_expire_time.setPlaceholder("锁定时间");
		field_sys_expire_time.setComment("锁定时间");
		fields.add(field_sys_expire_time);

		//sys_status
		Field field_sys_status = new Field();
		field_sys_status.setName("sys_status");
		field_sys_status.setType("varchar(40)");
		field_sys_status.setLabel("状态");
		field_sys_status.setComment("状态");
		field_sys_status.setPlaceholder("状态");
		fields.add(field_sys_status);

		//bk_01
		Field field_bk_01 = new Field();
		field_bk_01.setName("bk_01");
		field_bk_01.setType("varchar(40)");
		field_bk_01.setLabel("备用01");
		field_bk_01.setComment("备用01");
		field_bk_01.setPlaceholder("备用01");
		fields.add(field_bk_01);

		//bk_02
		Field field_bk_02 = new Field();
		field_bk_02.setName("bk_02");
		field_bk_02.setType("varchar(40)");
		field_bk_02.setLabel("备用02");
		field_bk_02.setComment("备用02");
		field_bk_02.setPlaceholder("备用02");
		fields.add(field_bk_02);

		//bk_03
		Field field_bk_03 = new Field();
		field_bk_03.setName("bk_03");
		field_bk_03.setType("varchar(40)");
		field_bk_03.setLabel("备用03");
		field_bk_03.setComment("备用03");
		field_bk_03.setPlaceholder("备用03");
		fields.add(field_bk_03);

		//bk_04
		Field field_bk_04 = new Field();
		field_bk_04.setName("bk_04");
		field_bk_04.setType("varchar(40)");
		field_bk_04.setLabel("备用04");
		field_bk_04.setComment("备用04");
		field_bk_04.setPlaceholder("备用04");
		fields.add(field_bk_04);

		//bk_05
		Field field_bk_05 = new Field();
		field_bk_05.setName("bk_05");
		field_bk_05.setType("varchar(40)");
		field_bk_05.setLabel("备用05");
		field_bk_05.setComment("备用05");
		field_bk_05.setPlaceholder("备用05");
		fields.add(field_bk_05);

		constraints = new LinkedList<TableConstraint>();
		apis = new LinkedList<API>();
		
		//Generate add method tempate
		API add = new API();
		add.setName("add");
		add.setDoc("Add new object");
		add.setReturn("Add result");
		List<APIParam> addAPIParams = new LinkedList<APIParam>();
		Map<String, String> validators4Object = new HashMap<String, String>();
		validators4Object.put("required", "");
		validators4Object.put("visitor", "");
		addAPIParams.add(generateAPIParam("o", tableName, validators4Object));
		add.setParams(addAPIParams);
		
		//Generate update method tempate
		API update = new API();
		update.setName("update");
		update.setDoc("Update object");
		update.setReturn("Update result");
		List<APIParam> updateAPIParams = new LinkedList<APIParam>();
		Map<String, String> validators4Update = new HashMap<String, String>();
		validators4Update.put("required", "");
		validators4Update.put("visitor", "");
		updateAPIParams.add(generateAPIParam("o", tableName, validators4Update));
		update.setParams(updateAPIParams);

		//Generate showItems tempalte
		API showItems = new API();
		showItems.setName("showItems");
		showItems.setDoc("View all items");
		showItems.setReturn("All items view");
		
		API deleteItems = new API();
		deleteItems.setName("deleteItems");
		deleteItems.setDoc("Delete specified items");
		deleteItems.setReturn("Delete result");

		List<APIParam> deleteItemsAPIParams = new LinkedList<APIParam>();
		Map<String, String> validators4Items = new HashMap<String, String>();
		validators4Items.put("required", "删除对象不能为空！");
		deleteItemsAPIParams.add(generateAPIParam("items", "int[]", validators4Items));
		deleteItems.setParams(deleteItemsAPIParams);

		//Template data for findPageData
		API findPageData = new API();
		findPageData.setName("findPageData");
		findPageData.setDoc("Retrieve specified page items");
		findPageData.setReturn("Target items");
		
		List<APIParam> findPageDataAPIParams = new LinkedList<APIParam>();
		Map<String, String> validators4Page = new HashMap<String, String>();
		validators4Page.put("required", "页码不能为空！");
		findPageDataAPIParams.add(generateAPIParam("page", "int", validators4Page));
		Map<String, String> validators4Rows = new HashMap<String, String>();
		validators4Rows.put("required", "页宽不能为空！");
		findPageDataAPIParams.add(generateAPIParam("rows", "int", validators4Rows));
		findPageData.setParams(findPageDataAPIParams);
		
		apis.add(add);
		apis.add(update);
		apis.add(showItems);
		apis.add(deleteItems);
		apis.add(findPageData);
	}
	
	private APIParam generateAPIParam(String name, String type, Map<String, String> validators){
		APIParam result = new APIParam();
		result.setName(name);
		result.setType(type);
		List<APIValidator> apiValidators = new LinkedList<APIValidator>();
		for(String validatorName : validators.keySet()){
			APIValidator validator = new APIValidator();
			validator.setType(validatorName);
			String message = validators.get(validatorName);
			if(null != message && message.length() > 0){
				validator.setMessage(message);
			}
			apiValidators.add(validator);
		}
		result.setValidators(apiValidators);
		return result;
	}
	public static long generateId(){
		Calendar calendar = Calendar.getInstance();
		return calendar.getTimeInMillis();
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name.replace(" ", "");
	}
	public String getModuleid() {
		return moduleid;
	}
	public void setModuleid(String moduleid) {
		this.moduleid = moduleid.replace(" ", "");
	}
	public String getTheme() {
		return theme;
	}
	public void setTheme(String theme) {
		this.theme = theme.replace(" ", "");
	}
	public String getComment() {
		return comment;
	}
	public void setComment(String comment) {
		this.comment = comment;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return name;
	}
	public long getId() {
		return id;
	}
	public List<Field> getFields() {
		return fields;
	}
	public void setFields(List<Field> fields) {
		this.fields = fields;
	}
	public List<TableConstraint> getConstraints() {
		return constraints;
	}
	public void setConstraints(List<TableConstraint> constraints) {
		this.constraints = constraints;
	}
	public List<API> getApis() {
		return apis;
	}
	public void setApis(List<API> apis) {
		this.apis = apis;
	}

	public String getFields_zh() {
		String zh = "";
		if(null != this.fields){
			for(Field f : this.fields){
				zh += f.getLabel() + ",";
			}
			int lastComma = zh.lastIndexOf(",");
			if((-1 != lastComma) && (lastComma == (zh.length() - 1))){
				zh = zh.substring(0, zh.length() - 1);
			}
		}
		return zh;
	}

	public String getFields_en() {
		String en = "";
		if(null != this.fields){
			for(Field f : this.fields){
				en += f.getName() + ",";
			}
			int lastComma = en.lastIndexOf(",");
			if((-1 != lastComma) && (lastComma == (en.length() - 1))){
				en = en.substring(0, en.length() - 1);
			}
		}
		return en;
	}

	public String getIdFieldName() {
		return idFieldName;
	}

	public void setIdFieldName(String idFieldName) {
		this.idFieldName = idFieldName;
	}
}
